package com.linln.admin.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.linln.common.config.SimpleJpaRepositoryImpl;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import java.lang.management.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author taofucheng <auntvt＠163.com>
 * @date 2021/3/20
 */
@ComponentScan(basePackages = "com.linln.admin")
@EnableJpaRepositories(basePackages = "com.linln.admin", repositoryBaseClass = SimpleJpaRepositoryImpl.class)
@EntityScan(basePackages = "com.linln.admin")
public class AdminAutoConfig {

    public static Map<String, Object> mem() {
        DecimalFormat df = new DecimalFormat("#.#");
        Map<String, Object> result = Maps.newHashMap();
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();
        MemoryUsage noheap = memoryMXBean.getNonHeapMemoryUsage();
        String jvmInitMem = df.format((memoryUsage.getInit() + noheap.getInit()) / 1024.0 / 1024.0) + "M";
        String jvmMaxMem = df.format((memoryUsage.getMax() + noheap.getMax()) / 1024.0 / 1024.0) + "M";
        String jvmUsedMem = df.format((memoryUsage.getUsed() + noheap.getUsed()) / 1024.0 / 1024.0) + "M";
        result.put("jvmInitMem", jvmInitMem);
        result.put("jvmMaxMem", jvmMaxMem);
        result.put("jvmUsedMem", jvmUsedMem);
        Runtime run = Runtime.getRuntime();
        long max = run.maxMemory();
        long total = run.totalMemory();
        long free = run.freeMemory();
        long usable = max - total + free;
        result.put("maxHeapMem", max);
        result.put("totalHeapMem", total);
        result.put("freeHeapMem", free);
        result.put("usableHeapMem", usable);

        try {
            OperatingSystemMXBean osXbean = ManagementFactory.getOperatingSystemMXBean();
            result.put("systemLoadAvg", osXbean.getSystemLoadAverage());
            String osJson = JSON.toJSONString(osXbean);
            JSONObject jsonObject = JSON.parseObject(osJson);
            result.put("processCpuLoad", (BigDecimal.valueOf(jsonObject.getDouble("processCpuLoad") * 100.0)).setScale(2, RoundingMode.HALF_UP));
            result.put("systemCpuLoad", (BigDecimal.valueOf(jsonObject.getDouble("systemCpuLoad") * 100.0)).setScale(2, RoundingMode.HALF_UP));
        } catch (Throwable ignore) {
        }

        try {
            result.put("loadClassCount", ManagementFactory.getClassLoadingMXBean().getTotalLoadedClassCount());
        } catch (Throwable ignore) {
        }

        try {
            result.put("threadCount", ManagementFactory.getThreadMXBean().getThreadCount());
            long[] deadLockedThreadIds = ManagementFactory.getThreadMXBean().findDeadlockedThreads();
            if (deadLockedThreadIds != null || deadLockedThreadIds.length > 0) {
                result.put("deadLockedThreadIds", deadLockedThreadIds);
                List<ThreadInfo> threads = new ArrayList<>();

                for (int i = 0; i < deadLockedThreadIds.length; ++i) {
                    try {
                        threads.add(ManagementFactory.getThreadMXBean().getThreadInfo(deadLockedThreadIds[i]));
                    } catch (Exception ignore) {
                    }
                }

                result.put("deadLockedThreads", threads);
            }
        } catch (Throwable ignore) {
        }

        return result;
    }
}
